篇首语:本文由编程笔记#小编为大家整理,主要介绍了Android 音频源码分析——AudioFlinger相关的知识,希望对你有一定的参考价值。
Android 音频源码分析——AndroidRecord录音(一)
Android 音频源码分析——AndroidRecord录音(二)
Android 音频源码分析——AndroidRecord音频数据传输流程
Android 音频源码分析——audioserver启动
Android 音频源码分析——AudioFlinger
Android 音频源码分析——AudioTrack设备选择
源码基于Android9.0
混音:把多种来源的声音,整合至一个立体音轨或单音轨中。
AudioFlinger和AudioPolicyService是音频中的两大服务,这里先整理下AudioFlinger。
AudioPolicyService时策略制定者,不和AudioHal直接交互;而AudioFlinger是策略执行者,与AudioHal层进行交互。
AudioFlinger运行在audioserver进程中,是一个音频服务。主要职责:
framework层hidl相关代码目录: frameworks/av/media/libaudiohal
hal层hidl相关代码: hardware/interfaces/audio
AudioFlinger通过hidl接口的方式调用hal层服务。有上一篇文章可知,启动AudioPolicyService时,会加载音频配置文件,然后根据配置加载HAL module。后续可以调用hal接口进行其他交互(设备选择、通路、读写数据等)。
AudioPolicyService并不直接于Hal层交互,而是由AudioFlinger和Hal通信,这里看看AudioFlinger加载音频模块。
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
if (name == NULL)
return AUDIO_MODULE_HANDLE_NONE;
if (!settingsAllowed())
return AUDIO_MODULE_HANDLE_NONE;
Mutex::Autolock _l(mLock);
return loadHwModule_l(name);
// loadHwModule_l() must be called with AudioFlinger::mLock held
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
sp<DeviceHalInterface> dev;
int rc &#61; mDevicesFactoryHal->openDevice(name, &dev);
//......
audio_module_handle_t handle &#61; (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
return handle;
加载hal层module,mAudioHwDevs保存handle 和AudioHwDevice.
接着看mDevicesFactoryHal->openDevice流程
mDevicesFactoryHal->openDevice(name, &dev);
>>DevicesFactoryHalHybrid::openDevice
>>
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device)
if (mDevicesFactory &#61;&#61; 0) return NO_INIT;
IDevicesFactory::Device hidlDevice;
status_t status &#61; nameFromHal(name, &hidlDevice);
if (status !&#61; OK) return status;
Result retval &#61; Result::NOT_INITIALIZED;
Return<void> ret &#61; mDevicesFactory->openDevice(
hidlDevice,
[&](Result r, const sp<IDevice>& result)
retval &#61; r;
if (retval &#61;&#61; Result::OK)
*device &#61; new DeviceHalHidl(result);
);
if (ret.isOk())
if (retval &#61;&#61; Result::OK) return OK;
else if (retval &#61;&#61; Result::INVALID_ARGUMENTS) return BAD_VALUE;
else return NO_INIT;
return FAILED_TRANSACTION;
hardware/interfaces/audio/core/all-versions/default/include/core/all-version/DevicesFactory.impl.h
Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb)
switch (device)
case IDevicesFactory::Device::PRIMARY:
return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
case IDevicesFactory::Device::A2DP:
return openDevice(AUDIO_HARDWARE_MODULE_ID_A2DP, _hidl_cb);
case IDevicesFactory::Device::USB:
return openDevice(AUDIO_HARDWARE_MODULE_ID_USB, _hidl_cb);
case IDevicesFactory::Device::R_SUBMIX:
return openDevice(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, _hidl_cb);
case IDevicesFactory::Device::STUB:
return openDevice(AUDIO_HARDWARE_MODULE_ID_STUB, _hidl_cb);
_hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
return Void();
int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev)
const hw_module_t* mod;
int rc;
rc &#61; hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
if (rc)
ALOGE("%s couldn&#39;t load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
if_name, strerror(-rc));
goto out;
rc &#61; audio_hw_device_open(mod, dev);
if (rc)
ALOGE("%s couldn&#39;t open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
if_name, strerror(-rc));
goto out;
if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN)
ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
rc &#61; -EINVAL;
audio_hw_device_close(*dev);
goto out;
return OK;
out:
*dev &#61; NULL;
return rc;
这里看看加载后的openOutput流程
status_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t *devices,
const String8& address,
uint32_t *latencyMs,
audio_output_flags_t flags)
if (devices &#61;&#61; NULL || *devices &#61;&#61; AUDIO_DEVICE_NONE)
return BAD_VALUE;
Mutex::Autolock _l(mLock);
sp<ThreadBase> thread &#61; openOutput_l(module, output, config, *devices, address, flags);
//......
return NO_INIT;
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t devices,
const String8& address,
audio_output_flags_t flags)
AudioHwDevice *outHwDev &#61; findSuitableHwDev_l(module, devices);
//......
AudioStreamOut *outputStream &#61; NULL;
status_t status &#61; outHwDev->openOutputStream(
&outputStream,
*output,
devices,
flags,
config,
address.string());
mHardwareStatus &#61; AUDIO_HW_IDLE;
if (status &#61;&#61; NO_ERROR)
if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)
sp<MmapPlaybackThread> thread &#61;
new MmapPlaybackThread(this, *output, outHwDev, outputStream,
devices, AUDIO_DEVICE_NONE, mSystemReady);
mMmapThreads.add(*output, thread);
return thread;
else
sp<PlaybackThread> thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
thread &#61; new OffloadThread(this, outputStream, *output, devices, mSystemReady);
else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask))
thread &#61; new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
else
thread &#61; new MixerThread(this, outputStream, *output, devices, mSystemReady);
mPlaybackThreads.add(*output, thread);
return thread;
return 0;
openinput 流程就先不分析了。
App和AudioFlinger间音频数据则通过共享内存的方式进行传输。
如下图AudioRecord的数据传输&#xff1a;
如下图AudioTrack的数据传输&#xff1a;
AudioFlinger是一个binder服务&#xff0c;app中的native层可以通过获取其binder服务从而进行交互。
如下示例&#xff1a;
const sp<IAudioFlinger>& audioFlinger &#61; AudioSystem::get_audio_flinger();
record &#61; audioFlinger->createRecord(input,
output,
&status);